package com.hdax.realm;

import com.hdax.entity.Employee;
import com.hdax.entity.Permission;
import com.hdax.entity.Role;
import com.hdax.mappers.PermissionMapper;
import com.hdax.mappers.RoleMapper;
import com.hdax.service.EmployeeService;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * 用户领域
 *
 * @author Aizen
 * @date 2022/05/04
 */

public class UserRealm extends AuthorizingRealm {

    /**
     * 员工服务
     */
    @Autowired
    private EmployeeService employeeService;
    @Autowired
    private PermissionMapper permissionMapper;


    /**
     * 授权
     *
     * @param principalCollection 主要收集
     * @return {@link AuthorizationInfo}
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        System.out.println("进入授权方法");
        //获得认证方法的第一个参数 employee
        Employee employee = (Employee)principalCollection.getPrimaryPrincipal();
        //获取该角色的 所有权限
        final List<Permission> pers = permissionMapper.getPermissionByRoleId(employee.getRole().getId());
        List<String> permissions = new ArrayList<>();
        //遍历权限信息 存放到 权限集合中
        pers.forEach(p->{
            permissions.add(p.getCode());
        });

        SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
        authorizationInfo.addRole(employee.getRole().getRole());
        authorizationInfo.addStringPermissions(permissions);

        return authorizationInfo;
    }

    /**
     * 认证
     * @param token 令牌
     * @return {@link AuthenticationInfo}
     * @throws AuthenticationException 身份验证异常
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        UsernamePasswordToken userToken = (UsernamePasswordToken) token;
        //连接真实数据库
        Employee employee = employeeService.findEmployeeByEmployeeCode(userToken.getUsername());
        if(employee == null){
            return null;
        }else if (employee.getOff()==2) {
            throw new RuntimeException("该用户已被禁用");
        }
        //密码可以加密: MD5  MD5盐值加密
        //密码认证，shiro帮你做,只需要像下面把正确的密码丢进去
        return new SimpleAuthenticationInfo(employee,employee.getPassword(), ByteSource.Util.bytes(employee.getSalt()),this.getName());
    }
}
